from datetime import datetime
from decimal import Decimal
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QGridLayout, QDialog, QWidget, QGroupBox, QLabel, QMenu
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QCursor
from .widgets.table_widget import CommonTableWidget
from .widgets.dialogs import BaseDialog, MessageOverlay
from .widgets.panels import BasePanel
from .widgets.basewidgets import *
from api import api
from common import config, utils, payments

SALE_HEADER_COLUMNS = {
    "销售单号": {"type": "text", "text": lambda x: x["code"], "width": 0.15},
    "客户": {"type": "text", "text": lambda x: x["customer"]["contact"]},
    "商品名称": {"type": "text", "text": lambda x: f"{x['items'][0]['product']['name']}{('(等)' if len(x['items']) > 1 else '')}"},
    "数量": {"type": "text", "text": lambda x: sum([item["quantity"] for item in x["items"]]), "width": 0.08, "sort": "quantity"},
    "总金额": {"type": "text", "text": lambda x: x["total_price"], "width": 0.1, "sort": "total_price"},
    "状态": {"type": "text", "text": lambda x: utils.SaleStatus(x["status"]).description, "width": 0.08},
    "开单时间": {"type": "text", "text": lambda x: utils.format_datetime(x["created_at"], "%Y-%m-%d")},
    "退货": {"type": "text", 
                "text": lambda x: "有" if x["saleReturns"] else "无",
                "color": lambda x: "red" if x["saleReturns"] else "",
                "width": 0.08},
    "操作": {"type": "action", "width": 0.2}
}

SALE_ITEMS_HEADER_COLUMNS = {
    "商品名称": {"type": "text", "text": lambda x: x["product"]["name"]},
    "数量": {"type": "text", "text": lambda x: x["quantity"]},
    "单价": {"type": "text", "text": lambda x: x["unit_price"]},
    "总金额": {"type": "text", "text": lambda x: x["total_price"]},
    "操作": {"type": "action"}
}

SALE_RETURN_ITEMS_HEADER_COLUMNS = {
    "商品名称": {"type": "text", "text": lambda x: x["product"]["name"]},
    "数量": {"type": "text", "text": lambda x: x["quantity"]},
    "单价": {"type": "text", "text": lambda x: x["unit_price"]},
    "已退数量": {"type": "text", "text": lambda x: x["quantity_returned"]},
    "退货数量": {"type": "spinbox"},
    "退货金额": {"type": "text", "text": lambda x: x["return_price"]}
}

class SalesPage(BasePanel):
    def __init__(self):
        super().__init__("销售管理")
        self.customers = []
        self.setup_ui()
        self.setup_context_menu()
        
    def setup_ui(self):
        # 搜索和操作区域
        search_widget = SearchPanel()
        search_layout = QHBoxLayout(search_widget)

        # 搜索类型
        self.search_type_combo = NormalComboBox()
        self.search_type_combo.setItems({"搜单号": 1, "搜商品": 2, "搜客户": 3})
        self.search_type_combo.currentIndexChanged.connect(self.change_search_type)

        # 搜索框
        self.search_input = SearchLineEdit()
        self.search_input.setPlaceholderText("根据销售单号搜索")
        self.search_input.textChanged.connect(self.flush_table)

        # 过滤商品
        self.product_input = AutoCompleteLineEdit(self.get_product_list, placeholder_text="根据商品名称或编码搜索")
        self.product_input.setVisible(False)
        self.product_input.selectedChanged.connect(self.flush_table)

        # 客户
        self.customer_input = AutoCompleteLineEdit(self.get_customer_list, placeholder_text="根据客户名称或手机号搜索")
        self.customer_input.setVisible(False)
        self.customer_input.selectedChanged.connect(self.flush_table)
        
        # 状态下拉框
        self.status_combo = NormalComboBox()
        self.status_combo.setItems({
            "全部状态": "",
            "待付款": utils.SaleStatus.UNPAID,
            "已付款": utils.SaleStatus.PAID,
            "已取消": utils.SaleStatus.CANCELLED
        })
        self.status_combo.currentIndexChanged.connect(self.flush_table)

        self.date_range_picker = DateRangeEdit(placeholder_text="不限时间范围")
        self.date_range_picker.onRangeChanged.connect(self.flush_table)

        # 添加销售单按钮
        self.add_sale_btn = BluePushButton("销售开单")
        self.add_sale_btn.clicked.connect(self.show_add_sale_dialog)

        search_layout.addWidget(self.search_type_combo)
        search_layout.addWidget(self.search_input)
        search_layout.addWidget(self.product_input)
        search_layout.addWidget(self.customer_input)
        search_layout.addWidget(self.status_combo)
        search_layout.addWidget(self.date_range_picker)
        search_layout.addStretch()
        search_layout.addWidget(self.add_sale_btn)

        self.main_layout.addWidget(search_widget)
        
        # 销售单表格
        table_widget = QWidget()
        table_widget.setObjectName("saleTable")
        table_layout = QVBoxLayout(table_widget)
        
        self.sale_table = CommonTableWidget(headers=SALE_HEADER_COLUMNS)
        self.sale_table.set_description("销售单流程: 开单(待付款) -> 付款(已付款)，"
                                      "付款后该销售单将不能修改，"
                                      "只有已付款的销售单才能退货。")
        self.sale_table.pageSizeChanged.connect(self.flush_table)
        self.sale_table.sortChanged.connect(self.flush_table)
        
        table_layout.addWidget(self.sale_table)
        self.main_layout.addWidget(table_widget)

    def setup_context_menu(self):
        super().setup_context_menu()
        self.sale_table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.sale_table.customContextMenuRequested.connect(self.show_context_menu)

    def add_extra_context_menus(self, menu, pos):
        menu.addSeparator()
        add_sale_action = menu.addAction("销售开单")
        add_sale_action.triggered.connect(self.show_add_sale_dialog)
        
        # 如果是在表格中点击
        sender = self.sender()
        if sender == self.sale_table and self.sale_table.itemAt(pos):
            row = self.sale_table.itemAt(pos).row()
            sale_data = self.sale_table.get_row_data(row)
            
            menu.addSeparator()
            
            # 销售单操作子菜单
            operations_menu = menu.addMenu("销售单操作")
            
            if sale_data["status"] == utils.SaleStatus.UNPAID:
                operations_menu.addAction("付款").triggered.connect(
                    lambda: self.pay_sale(row))
                operations_menu.addAction("编辑").triggered.connect(
                    lambda: self.edit_sale(row))
                close_action = operations_menu.addAction("关闭交易")
                close_action.triggered.connect(lambda: self.close_sale(row))
            elif sale_data["status"] == utils.SaleStatus.PAID:
                operations_menu.addAction("退货").triggered.connect(
                    lambda: self.return_sale(row))
                operations_menu.addAction("查看").triggered.connect(
                    lambda: self.edit_sale(row))
            else:
                operations_menu.addAction("查看").triggered.connect(
                    lambda: self.edit_sale(row))
            
            menu.addSeparator()
            
            # 销售单信息子菜单
            info_menu = menu.addMenu("销售单信息")
            info_menu.addAction(f"销售单号: {sale_data['code']}")
            info_menu.addAction(f"客户: {sale_data['customer']['contact']}")
            info_menu.addAction(f"状态: {utils.SaleStatus(sale_data['status']).description}")
            info_menu.addAction(f"总金额: ￥{sale_data['total_price']}")
            info_menu.addAction(f"创建时间: {utils.format_datetime(sale_data['created_at'])}")
            if sale_data["updated_at"]:
                info_menu.addAction(f"更新时间: {utils.format_datetime(sale_data['updated_at'])}")

    def change_search_type(self):
        self.search_input.setVisible(self.search_type_combo.currentData() == 1)
        self.product_input.setVisible(self.search_type_combo.currentData() == 2)
        self.customer_input.setVisible(self.search_type_combo.currentData() == 3)

    def get_product_list(self, keyword):
        if keyword:
            return api.get_products(keyword, status=True)["items"]
        else:
            self.flush_table()
            return []

    def flush_table(self):
        selected_product = self.product_input.get_selected_item()
        selected_customer = self.customer_input.get_selected_item()
        sales = api.get_sales(
            code=self.search_input.text(),
            product_id=selected_product["id"] if selected_product else None,
            customer_id=selected_customer["id"] if selected_customer else None,
            status=self.status_combo.currentData(),
            page=self.sale_table.current_page,
            per_page=self.sale_table.page_size,
            order_by=self.sale_table.sort_string,
            range_date=self.date_range_picker.get_range()
        )
        if not sales:
            return
            
        self.sale_table.set_total_items(sales["count"])
        self.sale_table.setRowCount(len(sales["items"]))
        for i, sale in enumerate(sales["items"]):
            self.sale_table.set_row_data(i, sale)
            action_buttons = []
            if sale["status"] == utils.SaleStatus.UNPAID:
                action_buttons.append({"text": "修改", "callback": self.edit_sale})
                action_buttons.append({"text": "付款", "callback": self.pay_sale})
                action_buttons.append({"text": "关闭", "callback": self.close_sale, "objectName": "deleteButton"})
            elif sale["status"] == utils.SaleStatus.PAID:
                action_buttons.append({"text": "查看", "callback": self.edit_sale})
                action_buttons.append({"text": "退货", "callback": self.return_sale})
            else:
                action_buttons.append({"text": "查看", "callback": self.edit_sale})
            self.sale_table.add_action_buttons(i, action_buttons)

    def edit_sale(self, row):
        dialog = AddSalesDialog(self, self.sale_table.get_row_data(row)["code"])
        if dialog.exec() == QDialog.Accepted and dialog.sale_data and dialog.sale_data["status"] == utils.SaleStatus.UNPAID:
            api.update_sale_items(dialog.sale_data["code"], dialog.sale_items)
            MessageOverlay.info(self, "销售单修改成功")
            self.flush_table()

    def pay_sale(self, row):
        sale_data = self.sale_table.get_row_data(row)
        dialog = PaymentDialog(self, sale_data["id"])
        if dialog.exec() == QDialog.Accepted:
            self.flush_table()
        
    def close_sale(self, row):
        if MessageOverlay.question(self, "关闭此交易后将不可恢复。\n是否关闭？") == MessageOverlay.ACCEPTED:
            api.update_sale(self.sale_table.get_row_data(row)["code"], utils.SaleStatus.CANCELLED)
            self.flush_table()

    def return_sale(self, row):
        """处理销售退货"""
        sale_data = self.sale_table.get_row_data(row)
        if sale_data["status"] != utils.SaleStatus.PAID:
            MessageOverlay.warning(self, "只有已付款的销售单才能退货")
            return
            
        dialog = ReturnSalesDialog(self, sale_data)
        if dialog.exec() == QDialog.Accepted:
            #TODO: 用户id
            api.add_sale_return(sale_data["code"], 1, dialog.return_items, dialog.reason)
            MessageOverlay.info(self, "退货成功")
            self.flush_table()

    def load_data(self):
        self.flush_table()

    def show_add_sale_dialog(self):
        dialog = AddSalesDialog(self)
        if dialog.exec() == QDialog.Accepted:
            #TODO: 用户id
            api.add_sale(dialog.customer["id"], 1, dialog.sale_items)
            MessageOverlay.info(self, "销售单添加成功")
            self.flush_table()

    def get_customer_list(self, keyword):
        if keyword:
            for customer in api.get_customers(keyword, page=0)["items"]:
                customer["name"] = f'{customer["contact"]}({utils.encrypt_phone(customer["phone"])})'
                yield customer
        else:
            self.flush_table()
            return []

class ReturnSalesDialog(BaseDialog):
    def __init__(self, parent=None, sales_data=None):
        super().__init__(parent)
        self.sales_data = api.get_sale(sales_data["code"])
        self.return_items = []  # 存储要退货的商品项目
        self.reason = ""
        self.setup_ui()
        
    def setup_ui(self):
        self.setWindowTitle("销售退货")
        self.setMinimumWidth(800)
        
        layout = QVBoxLayout(self)
        
        # 销售单信息显示
        info_group = QGroupBox("销售单信息")
        info_layout = QHBoxLayout(info_group)
        
        # 显示销售单基本信息
        info_layout.addWidget(QLabel("销售单号:"))
        info_layout.addWidget(QLabel(self.sales_data["code"]))
        
        info_layout.addWidget(QLabel("客户:"))
        info_layout.addWidget(QLabel(f'{self.sales_data["customer"]["contact"]}({utils.encrypt_phone(self.sales_data["customer"]["phone"])})'))
        
        info_layout.addWidget(QLabel("总金额:"))
        info_layout.addWidget(QLabel(f"{self.sales_data['total_price']}{config.CURRENCY_UNIT}"))

        info_layout.addWidget(QLabel("该单已退金额:"))
        returned_amount_label = QLabel()
        info_layout.addWidget(returned_amount_label)
        
        layout.addWidget(info_group)
        
        # 商品列表
        items_group = QGroupBox("商品列表")
        items_layout = QVBoxLayout(items_group)
        
        # 创建商品表格
        self.items_table = CommonTableWidget(headers=SALE_RETURN_ITEMS_HEADER_COLUMNS, pagination_position='none')
        self.items_table.setRowCount(len(self.sales_data["items"]))
        
        items_layout.addWidget(self.items_table)
        layout.addWidget(items_group)
        
        # 退货信息输入
        return_group = QGroupBox("退货信息")
        return_layout = QGridLayout(return_group)

        # 退货金额
        self.current_return_amount_label = NormalLabel(f"0.00{config.CURRENCY_UNIT}")
        return_layout.addWidget(QLabel("退货金额:"), 0, 0)
        return_layout.addWidget(self.current_return_amount_label, 0, 1)
        
        # 退货原因
        self.reason_combo = NormalComboBox()
        self.reason_combo.setItems(["质量问题", "客户不满意", "商品损坏", "其他原因"])
        self.reason_combo.currentIndexChanged.connect(self.on_reason_changed)
        return_layout.addWidget(QLabel("退货原因:"), 1, 0)
        return_layout.addWidget(self.reason_combo, 1, 1)
        
        # 备注
        self.remark_input = NormalTextEdit()
        self.remark_input.setPlaceholderText("请输入详细退货原因...")
        self.remark_input.setMaximumHeight(100)
        self.remark_input.setEnabled(False)
        return_layout.addWidget(QLabel("备注:"), 2, 0)
        return_layout.addWidget(self.remark_input, 2, 1)
        
        layout.addWidget(return_group)
        
        # 按钮布局
        button_layout = self.create_button_layout(self.validate_and_accept)
        layout.addLayout(button_layout)

        # 加载商品数据
        already_returned = {}
        total_returned_amount = 0
        for item in api.get_sale_returns(self.sales_data["id"]):
            for return_item in item["items"]:
                product_id = return_item["saleItem"]["product_id"]
                if product_id not in already_returned:
                    already_returned[product_id] = 0
                already_returned[product_id] += return_item["quantity"]
            total_returned_amount += item["total_price"]
        returned_amount_label.setText(f"{total_returned_amount}{config.CURRENCY_UNIT}")
        self.items_table.setRowCount(len(self.sales_data["items"]))
        for row, item in enumerate(self.sales_data["items"]):
            if item["product_id"] not in already_returned:
                item["quantity_available"] = item["quantity"]
                item["quantity_returned"] = 0
                item["return_price"] = 0
            else:
                item["quantity_available"] = item["quantity"] - already_returned[item["product_id"]]
                item["quantity_returned"] = already_returned[item["product_id"]]
                item["return_price"] = 0
            self.items_table.set_row_data(row, item)
            spinbox = NormalIntSpinBox()
            spinbox.setValue(0)
            spinbox.setRange(0, item["quantity_available"])
            spinbox.valueChanged.connect(lambda value, row=row:self.update_return_price(row, value))
            self.items_table.setCellWidget(row, 4, spinbox)
    
    def update_return_price(self, row, value):
        """更新退货金额"""
        row_data = self.items_table.get_row_data(row)
        row_data["current_quantity_returned"] = value
        row_data["return_price"] = row_data["unit_price"] * value
        self.items_table.set_row_data(row, row_data)
        self.items_table.fresh_item(row, 4)
        total_return_price = 0
        for i in range(self.items_table.rowCount()):
            total_return_price += self.items_table.get_row_data(i)["return_price"]
        self.current_return_amount_label.setText(f"{total_return_price}{config.CURRENCY_UNIT}")

    def on_reason_changed(self):
        self.remark_input.setEnabled(self.reason_combo.currentIndex() == self.reason_combo.count() - 1)

    def validate_and_accept(self):
        """验证并接受退货"""
        # 获取退货商品信息
        return_items = []
        for row in range(self.items_table.rowCount()):
            item = self.items_table.get_row_data(row)
            if item.get("current_quantity_returned", 0) > 0:
                return_items.append({
                    "sale_item_id": item["id"],
                    "quantity": item["current_quantity_returned"],
                    "unit_price": item["unit_price"],
                    "product": item["product"]
                })
        if not return_items:
            MessageOverlay.warning(self, "请至少选择一个商品进行退货")
            return
        self.reason = self.reason_combo.currentText() if self.reason_combo.currentIndex() != self.reason_combo.count() - 1 \
                        else self.remark_input.toPlainText()
        self.return_items = return_items

        if MessageOverlay.question(self, f"提交退货将不可撤消。是否提交以下退货内容:\n"
            f"{'\n'.join([f'{item["product"]["name"]}\t{item["quantity"]}{item["product"]["unit"]}' for item in return_items])}"
            f"\n共计: {sum([item["quantity"] * item["unit_price"] for item in return_items])}({config.CURRENCY_UNIT})") == MessageOverlay.ACCEPTED:
            self.accept()

class AddSalesDialog(BaseDialog):
    def __init__(self, parent=None, sale_code=None):
        super().__init__(parent)
        self.current_edit_row = -1
        self.sale_data = api.get_sale(sale_code) if sale_code else None
        self.sale_items = []
        self.setup_ui()
        
        if self.sale_data:
            self.load_sale_data()
    
    def setup_ui(self):
        # 根据模式设置窗口标题
        self.setWindowTitle("编辑销售单" if self.sale_data else "添加销售单")
        self.setMinimumWidth(900)  # 增加宽度以容纳左右两侧布局
        self.setMinimumHeight(450)
        
        main_layout = QHBoxLayout(self)  # 主布局改为水平布局
        
        # 左侧 - 销售单基本信息和商品添加表单
        left_widget = QWidget()
        left_layout = QVBoxLayout(left_widget)
        
        # 销售单基本信息
        basic_info_group = QGroupBox("销售单基本信息")
        basic_info_layout = QGridLayout(basic_info_group)
        
        # 销售单号
        self.code_input = NormalLineEdit()
        self.code_input.setReadOnly(True)
        basic_info_layout.addWidget(QLabel("销售单号:"), 0, 0)
        basic_info_layout.addWidget(self.code_input, 0, 1)
        
        # 客户
        self.customer_input = AutoCompleteLineEdit(self.search_customer, placeholder_text="搜索客户名称或手机号")
        if self.sale_data:
            self.customer_input.setText(f'{self.sale_data["customer"]["contact"]}({utils.encrypt_phone(self.sale_data["customer"]["phone"])})')
            self.customer_input.setEnabled(False)
        basic_info_layout.addWidget(QLabel("客户:"), 1, 0)
        basic_info_layout.addWidget(self.customer_input, 1, 1)
        
        # 状态
        self.status_label = NormalLabel(utils.SaleStatus(self.sale_data["status"]).description if
                                      self.sale_data else utils.SaleStatus.UNPAID.description)
        basic_info_layout.addWidget(QLabel("状态:"), 2, 0)
        basic_info_layout.addWidget(self.status_label, 2, 1)

        basic_info_layout.addWidget(QLabel("开单时间:"), 3, 0)
        basic_info_layout.addWidget(NormalLabel(utils.format_datetime(self.sale_data["created_at"])
                                    if self.sale_data else datetime.now().strftime("%Y-%m-%d")), 3, 1)

        if self.sale_data:
            basic_info_layout.addWidget(QLabel("最后更新时间:"), 4, 0)
            basic_info_layout.addWidget(NormalLabel(utils.format_datetime(self.sale_data["updated_at"])), 4, 1)

        left_layout.addWidget(basic_info_group)
        
        # 商品添加表单
        item_group = QGroupBox("添加商品")
        item_layout = QGridLayout(item_group)
        
        # 商品名称
        self.product_input = AutoCompleteLineEdit(self.get_product_list, placeholder_text="搜索商品名称或编码")
        self.product_input.selectedChanged.connect(self.on_product_selected)
        self.product_input.onSubmit.connect(self.add_item_to_list)
        item_layout.addWidget(QLabel("商品名称:"), 0, 0)
        item_layout.addWidget(self.product_input, 0, 1)

        # 库存
        self.stock_label = NormalLabel("0")
        item_layout.addWidget(QLabel("库存:"), 1, 0)
        item_layout.addWidget(self.stock_label, 1, 1)
        
        # 数量
        self.quantity_input = NormalIntSpinBox()
        self.quantity_input.setValue(1)  # 默认数量为1
        item_layout.addWidget(QLabel("数量:"), 2, 0)
        item_layout.addWidget(self.quantity_input, 2, 1)
        
        # 单价
        self.price_input = NormalFloatSpinBox()
        self.price_input.setReadOnly(True)
        item_layout.addWidget(QLabel("单价:"), 3, 0)
        item_layout.addWidget(self.price_input, 3, 1)
        
        # 总金额
        self.total_input = NormalFloatSpinBox()
        self.total_input.setReadOnly(True)
        item_layout.addWidget(QLabel("总金额:"), 4, 0)
        item_layout.addWidget(self.total_input, 4, 1)
        
        # 添加商品按钮
        button_layout = QHBoxLayout()
        self.add_item_btn = BluePushButton("添加到销售列表")
        self.add_item_btn.clicked.connect(self.add_item_to_list)
        self.cancel_edit_btn = WhitePushButton("取消编辑")
        self.cancel_edit_btn.setVisible(False)
        self.cancel_edit_btn.clicked.connect(self.cancel_edit)
        button_layout.addWidget(self.add_item_btn)
        button_layout.addWidget(self.cancel_edit_btn)
        item_layout.addLayout(button_layout, 5, 0, 1, 2, Qt.AlignCenter)
        
        left_layout.addWidget(item_group)

        # 扫码
        scan_group = QGroupBox("扫码添加")
        scan_layout = QVBoxLayout(scan_group)
        scan_label = ScanLabel(size=(280, 210))
        scan_label.scan_result.connect(self.on_scan_result)
        scan_layout.addWidget(scan_label)
        scan_label.start()
        left_layout.addWidget(scan_group)
        left_layout.addStretch()
        
        # 右侧 - 销售列表预览
        right_widget = QWidget()
        right_layout = QVBoxLayout(right_widget)
        
        # 销售列表标题
        right_layout.addWidget(QLabel("销售列表预览"))
        
        # 销售列表表格
        self.items_table = CommonTableWidget(self, SALE_ITEMS_HEADER_COLUMNS, 'none')
        right_layout.addWidget(self.items_table)
        
        # 总计信息
        total_widget = QWidget()
        total_layout = QHBoxLayout(total_widget)
        total_layout.addStretch()
        total_layout.addWidget(QLabel("商品总数:"))
        self.total_items_label = QLabel("0")
        total_layout.addWidget(self.total_items_label)
        total_layout.addWidget(QLabel("总金额:"))
        self.total_amount_label = QLabel("0.00")
        total_layout.addWidget(self.total_amount_label)
        right_layout.addWidget(total_widget)
        
        # 创建保存按钮布局并添加到右侧布局底部
        button_layout = self.create_button_layout(self.validate_and_accept)
        right_layout.addLayout(button_layout)
        
        # 添加左右两侧到主布局
        main_layout.addWidget(left_widget, 1)  # 左侧占比1
        main_layout.addWidget(right_widget, 2)  # 右侧占比2

        self.quantity_input.valueChanged.connect(self.update_total)
        if self.sale_data:
            self.code_input.setText(self.sale_data["code"])
            if self.sale_data["status"] != utils.SaleStatus.UNPAID:
                self.product_input.setReadOnly(True)
                self.add_item_btn.setEnabled(False)
                self.items_table.setColumnHidden(len(SALE_ITEMS_HEADER_COLUMNS)-1, True)
        else:
            self.code_input.setText("自动生成")

    def get_product_list(self, keyword):
        if keyword:
            return api.get_products(keyword, status=True)["items"]
        else:
            self.price_input.setValue(0)
            self.total_input.setValue(0)
            return []
        
    def update_total(self):
        quantity = self.quantity_input.value()
        price = self.price_input.value()
        total = quantity * price
        self.total_input.setValue(total)

    def on_product_selected(self, product):
        price = product["price"]
        self.price_input.setValue(price)
        if product["stock"] > 0:
            if product["stock"] < product["lowest_stock"]:
                self.stock_label.setText(f"{product['stock']}（库存不足⚠️）")
            else:
                self.stock_label.setText(f"{product['stock']}")
            self.quantity_input.setRange(1, product["stock"])
            self.quantity_input.setValue(1)
            self.total_input.setValue(price)
        else:
            self.stock_label.setText("无库存⚠️")
            self.quantity_input.setRange(0, 0)
            self.total_input.setValue(0)
    
    def add_item_to_list(self):
        """添加商品到销售列表"""
        quantity = self.quantity_input.value()
        
        # 如果是编辑模式，更新现有行
        if self.current_edit_row >= 0:
            if quantity <= 0:
                self.delete_item(self.current_edit_row)
                return
            item_data = self.items_table.get_row_data(self.current_edit_row)
            item_data.update({
                "quantity": quantity,
                "total_price": Decimal(self.total_input.value()),
            })
            self.items_table.set_row_data(self.current_edit_row, item_data)
            self.product_input.setReadOnly(False)
            self.current_edit_row = -1
            self.add_item_btn.setText("添加到销售列表")
            self.cancel_edit_btn.setVisible(False)
            self.add_item_btn.parent().setTitle("添加商品")
        else:
            selected_product = self.product_input.get_selected_item()
            if not selected_product:
                MessageOverlay.warning(self, "请选择商品")
                self.product_input.setFocus()
                return
            if quantity <= 0:
                MessageOverlay.warning(self, "数量必须大于0")
                self.quantity_input.setFocus()
                return
            for item in self.sale_items:
                if item["product"]["id"] == selected_product["id"] and item["unit_price"] == Decimal(self.price_input.value()):
                    if item["quantity"] + quantity > selected_product["stock"]:
                        MessageOverlay.warning(self, f"库存不足，最多只能添加{selected_product['stock'] - item['quantity']}个")
                        return
                    item["quantity"] += quantity
                    item["total_price"] += Decimal(self.total_input.value())
                    break
            else:
                if len(self.sale_items) >= config.SALE_MAX_PRODUCT_COUNT:
                    MessageOverlay.warning(self, f"销售单最多只能包含{config.SALE_MAX_PRODUCT_COUNT}种商品")
                    return
                self.sale_items.append({
                    "product": selected_product,
                    "quantity": quantity,
                    "unit_price": Decimal(self.price_input.value()),
                    "total_price": Decimal(self.total_input.value()),
                })
        
        # 清空输入框
        self.product_input.clear()
        self.quantity_input.setValue(1)
        self.price_input.setValue(0)
        self.total_input.setValue(0)
        self.refresh_items_table()
    
    def edit_item(self, row):
        """编辑销售列表中的商品"""
        if row < 0 or row >= len(self.sale_items):
            return
        
        item = self.items_table.get_row_data(row)
        self.product_input.setText(item["product"]["name"])
        self.product_input.setReadOnly(True)
        self.quantity_input.setValue(item["quantity"])
        self.price_input.setValue(item["unit_price"])
        self.total_input.setValue(item["total_price"])
        
        # 标记当前正在编辑的行
        self.current_edit_row = row
        self.add_item_btn.setText("更新商品")
        self.cancel_edit_btn.setVisible(True)
        self.add_item_btn.parent().setTitle("更新商品")

    def cancel_edit(self):
        self.product_input.setReadOnly(False)
        self.current_edit_row = -1
        self.add_item_btn.setText("添加到销售列表")
        self.cancel_edit_btn.setVisible(False)
        self.add_item_btn.parent().setTitle("添加商品")

    def delete_item(self, row):
        """删除销售列表中的商品"""
        if row < 0 or row >= len(self.sale_items):
            return
        
        if MessageOverlay.question(self, "确定要移除这个商品吗？") == MessageOverlay.ACCEPTED:
            del self.sale_items[row]
            self.refresh_items_table()
    
    def refresh_items_table(self):
        """刷新销售列表表格"""
        if not self.sale_items:
            self.items_table.setRowCount(0)
            return
        self.items_table.setRowCount(len(self.sale_items))
        
        total_items = 0
        total_amount = Decimal(0)
        
        for row, item in enumerate(self.sale_items):
            self.items_table.set_row_data(row, item)
            self.items_table.add_action_buttons(row, [{"text":"修改", "callback": self.edit_item},
                                                      {"text":"移除", "callback": self.delete_item, "objectName": "deleteButton"}])

            total_items += item["quantity"]
            total_amount += item["total_price"]
        
        self.total_items_label.setText(str(total_items))
        self.total_amount_label.setText(f"{total_amount:.2f}")
    
    def load_sale_data(self):
        # 设置基本信息
        self.code_input.setText(self.sale_data["code"])
        self.customer_input.setText(f'{self.sale_data["customer"]["contact"]}({utils.encrypt_phone(self.sale_data["customer"]["phone"])})')
        
        self.sale_items = self.sale_data["items"]
        self.refresh_items_table()
    
    def validate_and_accept(self):
        if not self.sale_data and not self.customer_input.get_selected_item():
            MessageOverlay.warning(self, "请选择客户")
            self.customer_input.setFocus()
            return
        if not self.sale_items:
            MessageOverlay.warning(self, "请至少添加一个商品")
            self.product_input.setFocus()
            return
        self.accept()

    def search_customer(self, keyword):
        for customer in api.get_customers(keyword, page=0)["items"]:
            customer["name"] = f'{customer["contact"]}({utils.encrypt_phone(customer["phone"])})'
            yield customer

    def on_scan_result(self, result):
        product = api.get_product(result)
        if product:
            self.current_edit_row = -1
            if product["stock"] > 0:
                self.product_input.set_item(product["name"], product)
                self.quantity_input.setValue(1)
                self.price_input.setValue(product["price"])
                self.total_input.setValue(product["price"])
                self.stock_label.setText(f"{product['stock']}")
                self.add_item_btn.click()
            else:
                MessageOverlay.warning(self, "商品无库存")
        else:
            MessageOverlay.warning(self, f"未找到商品(编码: {result})")

    @property
    def customer(self):
        return self.customer_input.get_selected_item()

class PaymentDialog(BaseDialog):
    def __init__(self, parent, sale_id):
        super().__init__(parent)
        self.sale_info = api.get_sale(sale_id)
        self.setWindowTitle("支付方式")
        self.setFixedSize(360, 560)
        self.scan_label = None
        self.setup_ui()

    def setup_ui(self):
        # 主布局
        layout = QVBoxLayout(self)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        # 金额显示
        amount_group = QGroupBox("支付金额")
        amount_layout = QVBoxLayout(amount_group)
        amount_label = NormalLabel(f"{self.sale_info['total_price']}{config.CURRENCY_UNIT}")
        amount_label.setStyleSheet("font-size: 24px; font-weight: bold;")
        amount_label.setAlignment(Qt.AlignCenter)
        amount_layout.addWidget(amount_label)
        layout.addWidget(amount_group)

        # 支付方式选择
        method_group = QGroupBox("选择支付方式")
        method_layout = QVBoxLayout(method_group)
        self.method_combo = NormalComboBox()
        self.method_combo.setItems({payment.description: payment for payment in utils.PaymentMethod})
        self.method_combo.currentIndexChanged.connect(self.on_method_change)
        method_layout.addWidget(self.method_combo)
        layout.addWidget(method_group)

        # 扫码区域
        scan_group = QGroupBox("扫码支付")
        scan_layout = QVBoxLayout(scan_group)
        self.scan_label = ScanLabel(size=(300, 200))        # 扫码结果
        self.scan_label.scan_result.connect(self.on_scan_result)
        scan_layout.addWidget(self.scan_label)
        layout.addWidget(scan_group)

        # 状态显示
        self.status_label = NormalLabel("请选择支付方式")
        self.status_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.status_label)

        # 按钮
        btn_layout = QHBoxLayout()
        self.ok_button = BluePushButton("确认支付")
        self.cancel_button = WhitePushButton("取消")
        btn_layout.addWidget(self.ok_button)
        btn_layout.addWidget(self.cancel_button)
        layout.addLayout(btn_layout)

        # 连接信号
        self.ok_button.clicked.connect(self.on_confirm)
        self.cancel_button.clicked.connect(self.reject)

        # 初始化界面状态
        self.on_method_change()

    def on_method_change(self):
        method = self.method_combo.currentData()
        if method == utils.PaymentMethod.CASH:
            self.scan_label.setVisible(False)
            self.status_label.setText("现金支付，请确认收款")
            self.ok_button.setEnabled(True)
        else:
            self.scan_label.setVisible(True)
            self.scan_label.start()
            self.status_label.setText(f"请出示{self.method_combo.currentText()}付款码")
            self.ok_button.setEnabled(False)

    def on_scan_result(self, result):
        if not result:
            return
        self.status_label.setText("正在支付...")
        if api.pay_sale(self.sale_info["id"], self.method_combo.currentData(), result):
            self.status_label.setText("支付成功")
            self.accept()
        else:
            self.status_label.setText("支付失败")

    def on_confirm(self):
        if self.method_combo.currentData() == utils.PaymentMethod.CASH:
            if api.pay_sale(self.sale_info["id"], self.method_combo.currentData(), ""):
                self.status_label.setText("支付成功")
                self.accept()
            else:
                self.status_label.setText("支付失败")


